/**
 * @file 语音助理
 * @author 抖音@程序员李钟意
 */
import debounce from "./debounce.js";

export default class Assistant {
  name = "";
  sayInstance = null;
  recognition = null;
  debounced = () => {}; /*语音识别调用方法*/
  voiceLang = "zh-CN"; /*"zh-HK"*/

  status = 1; /*1 播放 0 不播放*/
  volume = 0.5; /*声音大小*/

  constructor({ name, voiceLang }) {
    this.name = voiceLang;
    this.name = name;
    this.debounced = debounce(this.saySpeech, 1000, false);

    /*选择页面上的 "开始" 按钮*/
    const actionButton = document.querySelector("#action-button");
    /*选择页面上的输出段落*/
    const output = document.querySelector("#output");

    /*初始化*/
    this.saySpeech("");

    this.recognition = this.createRecognition((textContent) => {
      console.log("识别结果 :>> ", textContent);

      output.textContent = textContent.replace(/(李忠义|李忠英)/gi, "李钟意");
    });

    /*识别结束*/
    this.recognition.addEventListener("end", (event) => {
      if (/(停止|关闭|结束|stop)/gi.test(output.textContent)) {
        console.log("111 :>> ", 111);
        output.textContent = "";
        actionButton.textContent = "开始";
        this.setStatus(0);
        this.recognition.stop();
        setTimeout(() => {
          this.recognition.start();
        });
        return;
      }
      if (/(打开|开始|start|open)/gi.test(output.textContent)) {
        this.recognition.start();
        actionButton.textContent = "停止";
        this.setStatus(1);
      }
      console.log("this.status :>> ", this.status);

      if (this.status === 0) {
        output.textContent = "";
        setTimeout(() => {
          this.recognition.start();
        });
        return;
      }

      this.debounced(output.textContent);

      if (/(中文)/gi.test(output.textContent)) {
        this.setVoiceLang("zh-CN");
        const textContent = "好的已经切换中文";
        output.textContent = textContent;
        this.debounced(textContent);
      }
      if (/(粤语)/gi.test(output.textContent)) {
        this.setVoiceLang("zh-HK");
        const textContent = "好的已经切换粤语";
        output.textContent = textContent;
        this.debounced(textContent);
      }
      if (/(这是|是谁)/gi.test(output.textContent)) {
        const textContent = "我是你的人工智能助理";
        output.textContent = textContent;
        this.debounced(textContent);
      }
      if (/(声音|音量)/gi.test(output.textContent)) {
        if (output.textContent === "声音" || output.textContent === "音量") {
          const textContent = `音量为${this.volume}`;
          output.textContent = textContent;
          this.setVolume(1);
          this.debounced(textContent);
        }
        if (/(最大)/gi.test(output.textContent)) {
          /*大一点 小一点 最大 最小 静音 50*/
          const textContent = "音量已经最大";
          output.textContent = textContent;
          this.setVolume(1);
          this.debounced(textContent);
        } else if (/(最小)/gi.test(output.textContent)) {
          const textContent = "音量已经最小";
          output.textContent = textContent;
          this.setVolume(0.05);
          this.debounced(textContent);
        } else if (/(大一点)/gi.test(output.textContent)) {
          console.log("1 :>> ", 1);
          const volume = Math.min(1, this.volume + 0.1);
          let textContent = `好的音量为${(volume * 100).toFixed(0)}`;
          if ((volume * 100).toFixed(0) === 100) {
            textContent = "音量已经最大";
          }
          /*console.log("volume :>> ", volume);*/
          this.setVolume(volume);
          output.textContent = textContent;
          this.debounced(textContent);
        } else if (/(大一点)/gi.test(output.textContent)) {
          console.log("1 :>> ", 1);
          const volume = Math.min(1, this.volume + 0.1);
          let textContent = `好的音量为${(volume * 100).toFixed(0)}`;
          if ((volume * 100).toFixed(0) === 100) {
            textContent = "音量已经最大";
          }
          console.log("volume :>> ", volume);
          this.setVolume(volume);
          output.textContent = textContent;
          this.debounced(textContent);
        } else if (/(小一点)/gi.test(output.textContent)) {
          console.log("1 :>> ", 1);
          const volume = Math.max(0, this.volume - 0.1);
          let textContent = `好的音量为${(volume * 100).toFixed(0)}`;
          if ((volume * 100).toFixed(0) === 0) {
            textContent = "音量已经最小";
          }
          console.log("volume :>> ", volume);
          this.setVolume(volume);
          output.textContent = textContent;
          this.debounced(textContent);
        } else if (/(\d+)/gi.test(output.textContent)) {
          const volume = output.textContent.match(/\d+/);
          const textContent = `音量为${volume}`;
          output.textContent = textContent;
          this.setVolume(Number((volume / 100).toFixed(2)));
          this.debounced(textContent);
        } else if (/(静音)/gi.test(output.textContent)) {
          const textContent = "";
          output.textContent = textContent;
          this.setVolume(0);
          this.debounced(textContent);
        }
      }
    });

    /*给 "开始" 按钮添加点击事件*/
    actionButton.addEventListener("click", () => {
      if (actionButton.textContent === "停止") {
        actionButton.textContent = "开始";

        /*在使用 recognition.stop() 方法停止 WebkitSpeechRecognition 语音识别时，*/
        /*会停止当前正在进行的语音识别。如果要重新开始语音识别，需要再次调用 recognition.start() 方法。*/
        /*如果要停止 WebkitSpeechRecognition 并释放所有资源，可以调用recognition.abort()。*/
        /*this.recognition.stop();*/
        /*停止后，不能重新调用 recognition.start() 方法。需要重新实例化。*/
        this.recognition.abort();
      } else {
        actionButton.textContent = "停止";
        output.textContent = "";
        /*开始识别*/
        this.recognition.start();
      }
    });
  }

  createRecognition(callback = () => {}) {
    if (typeof callback !== "function") {
      console.error("createRecognition callback is not function!");
      callback = () => {};
    }
    /*如果浏览器支持 Web Speech API*/
    if (!("webkitSpeechRecognition" in window)) {
      console.error("浏览器不支持 Web Speech API");
      return;
    }
    /*创建一个新的 SpeechRecognition 对象*/
    const recognition = new webkitSpeechRecognition();

    /*设置连续识别模式*/
    recognition.continuous = false;
    /*设置为输出临时结果*/
    recognition.interimResults = true;

    /*当有识别结果时调用的回调函数*/
    recognition.onresult = (event) => {
      /*临时识别结果*/
      let interimTranscript = "";
      /*最终识别结果*/
      let finalTranscript = "";

      /*  console.log("event.results :>> ", event.results);*/

      /*遍历所有的识别结果*/
      for (let i = event.resultIndex; i < event.results.length; i++) {
        /*获取当前的识别结果*/
        const transcript = event.results[i][0].transcript;

        /*console.log("transcript", transcript);*/
        /*如果当前的识别结果是最终结果*/
        if (event.results[i].isFinal) {
          /*将当前结果添加到最终识别结果中*/
          finalTranscript += transcript;
        } else {
          /*否则，将当前结果添加到临时识别结果中*/
          interimTranscript += transcript;
        }
      }

      /*如果有最终识别结果，则输出最终识别结果；否则，输出临时识别结果*/
      const textContent = finalTranscript || interimTranscript;

      callback(textContent);
    };
    return recognition;
  }

  saySpeech(textContent) {
    /*播放文本实例*/
    const sayInstance = new window.SpeechSynthesisUtterance(textContent);
    /*修改播放的声音大小*/
    sayInstance.volume = this.volume;
    /*修改语言*/
    sayInstance.voice = window.speechSynthesis
      .getVoices()
      .filter((voice) => voice.lang === this.voiceLang)[0];
    /*播放语音*/
    window.speechSynthesis.speak(sayInstance);

    /*Speech ended*/
    sayInstance.onend = (event) => {
      const output = document.querySelector("#output");
      output.textContent = "";
      console.log("this.recognition :>> ", this.recognition);
      this.recognition && this.recognition.start();
    };

    this.sayInstance = sayInstance;
  }

  /*设置语言*/
  setVoiceLang(voiceLang) {
    this.voiceLang = voiceLang;
  }

  /*设置状态*/
  setStatus(status) {
    /*0 不播放 1 播放*/
    this.status = status;
  }

  /*设置声音大小*/
  setVolume(volume) {
    this.volume = volume;
  }
}
